﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace createShapeWithFictory
{
    class MyException : Exception
    {
        public MyException(string message) : base(message) { }
    }
    abstract class Shape
    {
        public abstract double area();
        public abstract bool isLegal();
    }

    class Rectangle : Shape
    {
        private int height { get; set; }
        private int width { get; set; }

        public Rectangle(int height, int width)
        {
            this.height = height;
            this.width = width;
        }
        public override double area()
        {
            if (!isLegal())
            {
                throw new MyException("The rectangle is illegal.");
            }
            return height * width;
        }

        public override bool isLegal()
        {
            if (width > 0 && height > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    class Square : Shape
    {
        private int side { get; set; }

        public Square(int side)
        {
            this.side = side;
        }

        public override double area()
        {
            if (!isLegal())
            {
                throw new MyException("The Square is illegal.");
            }
            return side * side;
        }

        public override bool isLegal()
        {
            if (side > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    class Triangle : Shape
    {
        private int side1 { get; set; }
        private int side2 { get; set; }
        private int side3 { get; set; }

        public Triangle(int side1, int side2, int side3)
        {
            this.side1 = side1;
            this.side2 = side2;
            this.side3 = side3;
        }
        public override double area()
        {
            if (!isLegal())
            {
                throw new MyException("The triangle is illegal.");
            }
            double p = (side1 + side2 + side3) / 2;
            return Math.Sqrt(p * (p - side1) * (p - side2) * (p - side3));
        }

        public override bool isLegal()
        {
            if (side1 > 0 && side2 > 0 && side3 > 0 && side1 + side2 > side3 && side1 + side3 > side2 && side2 + side3 > side1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    class shapeFictory
    {
        public Shape createShape(string name,int a,int b,int c)
        {
            switch (name) {
                case "rectangle": {
                        Rectangle rectangle = new Rectangle(a, b);
                        if (rectangle.isLegal()) { return rectangle; }
                        else { throw new MyException("The reactangle is illegal."); }
                    }
                case "square":{
                        Square square = new Square(a);
                        if (square.isLegal()) { return square; }
                        else { throw new MyException("The square is illegal.");  }
                    }
                case "triangle":{
                        Triangle triangle = new Triangle(a, b,c);
                        if (triangle.isLegal()) { return triangle; }
                        else { throw new MyException("The triangle is illegal.");  }
                    }
                default:throw new MyException("The shape is not defined.");
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            string[] shapeName = { "rectangle","square","triangle"};
            shapeFictory fictory = new shapeFictory();
            double sum = 0;
            Random randomIndex = new Random();
            Random randomA = new Random();
            Random randomB = new Random();
            Random randomC = new Random();
            for (int i = 0; i < 10; i++)
            {
                int index = randomIndex.Next(0,3);
                Shape shape;
                try
                {
                    shape = fictory.createShape(shapeName[index], randomA.Next(-100,100), randomB.Next(-100,100), randomC.Next(-100,100));
                    sum += shape.area();
                }
                catch(MyException e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            Console.WriteLine(sum);
            Console.ReadKey();
        }
    }
}
